<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, viewport-fit=cover"/>
<meta name="description" content="TypeScript: An HTML panel that displays the properties of some model data and allows the user to edit their values."/> 
<link rel="stylesheet" href="../assets/css/style.css"/> 
<!-- Copyright 1998-2021 by Northwoods Software Corporation. -->
<title>Data Inspector</title>
</head>

<body>
  <!-- This top nav is not part of the sample code -->
  <nav id="navTop" class="w-full z-30 top-0 text-white bg-nwoods-primary">
    <div class="w-full container max-w-screen-lg mx-auto flex flex-wrap sm:flex-nowrap items-center justify-between mt-0 py-2">
      <div class="md:pl-4">
        <a class="text-white hover:text-white no-underline hover:no-underline
        font-bold text-2xl lg:text-4xl rounded-lg hover:bg-nwoods-secondary " href="../">
          <h1 class="mb-0 p-1 ">GoJS</h1>
        </a>
      </div>
      <button id="topnavButton" class="rounded-lg sm:hidden focus:outline-none focus:ring" aria-label="Navigation">
        <svg fill="currentColor" viewBox="0 0 20 20" class="w-6 h-6">
          <path id="topnavOpen" fill-rule="evenodd" d="M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM9 15a1 1 0 011-1h6a1 1 0 110 2h-6a1 1 0 01-1-1z" clip-rule="evenodd"></path>
          <path id="topnavClosed" class="hidden" fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path>
        </svg>
      </button>
      <div id="topnavList" class="hidden lg:text-base sm:block items-center w-auto mt-0 text-white p-0 z-20">
        <ul class="list-reset list-none font-semibold flex justify-end flex-wrap sm:flex-nowrap items-center px-0 pb-0">
          <li class="p-1 sm:p-0"><a class="topnav-link" href="../learn/">Learn</a></li>
          <li class="p-1 sm:p-0"><a class="topnav-link" href="../samples/">Samples</a></li>
          <li class="p-1 sm:p-0"><a class="topnav-link" href="../intro/">Intro</a></li>
          <li class="p-1 sm:p-0"><a class="topnav-link" href="../api/">API</a></li>
          <li class="p-1 sm:p-0"><a class="topnav-link" href="https://www.nwoods.com/products/register.html">Register</a></li>
          <li class="p-1 sm:p-0"><a class="topnav-link" href="../download.html">Download</a></li>
          <li class="p-1 sm:p-0"><a class="topnav-link" href="https://forum.nwoods.com/c/gojs/11">Forum</a></li>
          <li class="p-1 sm:p-0"><a class="topnav-link" href="https://www.nwoods.com/contact.html"
           target="_blank" rel="noopener" onclick="getOutboundLink('https://www.nwoods.com/contact.html', 'contact');">Contact</a></li>
          <li class="p-1 sm:p-0"><a class="topnav-link" href="https://www.nwoods.com/sales/index.html"
           target="_blank" rel="noopener" onclick="getOutboundLink('https://www.nwoods.com/sales/index.html', 'buy');">Buy</a></li>
        </ul>
      </div>
    </div>
    <hr class="border-b border-gray-600 opacity-50 my-0 py-0" />
  </nav>
  <div class="md:flex flex-col md:flex-row md:min-h-screen w-full max-w-screen-xl mx-auto">
    <div id="navSide" class="flex flex-col w-full md:w-48 text-gray-700 bg-white flex-shrink-0"></div>
    <!-- * * * * * * * * * * * * * -->
    <!-- Start of GoJS sample code -->
    

    <div class="p-4 w-full">
<link rel='stylesheet' href='DataInspector.css' />
<div id="sample">
  <span style="display: inline-block; vertical-align: top;">
  <div style="margin-left: 10px;">
  <div id="myDiagramDiv" style="border: solid 1px black; width:400px; height:400px;"></div>
  </div>
</span>
  <span style="display: inline-block; vertical-align: top;">
  Selected Part:<br/>
  <div id="myInspectorDiv1" class="inspector"> </div><br/>
  First Node's data:<br />
  <div id="myInspectorDiv2" class="inspector"> </div><br />
  Model.modelData:<br />
  <div id="myInspectorDiv3" class="inspector"> </div><br />
</span>
  <div>
    <p>An HTML-based inspector that displays and allows editing of data for the selected Part (if any), or for a particular JavaScript
        object, or for the shared <a>Model.modelData</a> object, which exists even if there are no nodes or links.
    <p>The inspector code lies in <a href="DataInspector.ts">DataInspector.ts</a> and <a href="DataInspector.css">DataInspector.css</a>.
        This code is meant to be a starting point for making your own model data inspector.
    <p>On browsers that support it, color types display a color picker. There are various plugins and polyfills for this functionaltiy
        if you wish to extend the data inspector.
    <p>This shows the contents of the model after each transaction:
        <pre id="savedModel" />
  </div>
</div>

<script type="module" id="code">
  import * as go from "../release/go-module.js";
  import { Inspector } from './DataInspector.js';

  if (window.goSamples) goSamples(); // init for the samples -- you don't need to call this
  const $ = go.GraphObject.make; // for conciseness in defining templates

  const myDiagram =
    $(go.Diagram, 'myDiagramDiv', // create a Diagram for the DIV HTML element
      {
        'animationManager.isEnabled': false,
        // allow double-click in background to create a new node
        'clickCreatingTool.archetypeNodeData': { text: 'Node', color: 'white' },
        // allow Ctrl-G to call groupSelection()
        'commandHandler.archetypeGroupData': { text: 'Group', isGroup: true, color: 'blue' },
        // enable undo & redo
        'undoManager.isEnabled': true,
        // automatically show the state of the diagram's model on the page
        'ModelChanged': function (e) {
            if (e.isTransactionFinished) {
                const elt = document.getElementById('savedModel');
                if (elt !== null)
                    elt.textContent = myDiagram.model.toJson();
            }
        }
    });
  // These nodes have text surrounded by a rounded rectangle
  // whose fill color is bound to the node data.
  // The user can drag a node by dragging its TextBlock label.
  // Dragging from the Shape will start drawing a new link.
  myDiagram.nodeTemplate =
      $(go.Node, 'Auto', { locationSpot: go.Spot.Center }, new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify), $(go.Shape, 'Rectangle', {
          stroke: null, strokeWidth: 0,
          fill: 'white',
          portId: '', cursor: 'pointer',
          // allow all kinds of links from and to this port
          fromLinkable: true, fromLinkableSelfNode: true, fromLinkableDuplicates: true,
          toLinkable: true, toLinkableSelfNode: true, toLinkableDuplicates: true
      }, new go.Binding('fill', 'color')), $(go.TextBlock, {
          font: 'bold 18px sans-serif',
          stroke: '#111',
          margin: 8,
          isMultiline: false,
          editable: true // allow in-place editing by user
      }, new go.Binding('text', 'text').makeTwoWay()));
  // The link shape and arrowhead have their stroke brush data bound to the "color" property
  myDiagram.linkTemplate =
      $(go.Link, { toShortLength: 3, relinkableFrom: true, relinkableTo: true }, // allow the user to relink existing links
      $(go.Shape, { strokeWidth: 2 }, new go.Binding('stroke', 'color')), $(go.Shape, { toArrow: 'Standard', stroke: null }, new go.Binding('fill', 'color')));
  // Groups consist of a title in the color given by the group node data
  // above a translucent gray rectangle surrounding the member parts
  myDiagram.groupTemplate =
      $(go.Group, 'Vertical', {
          selectionObjectName: 'PANEL',
          ungroupable: true
      }, // enable Ctrl-Shift-G to ungroup a selected Group
      $(go.TextBlock, {
          font: 'bold 19px sans-serif',
          isMultiline: false,
          editable: true // allow in-place editing by user
      }, new go.Binding('text', 'text').makeTwoWay(), new go.Binding('stroke', 'color')), $(go.Panel, 'Auto', { name: 'PANEL' }, $(go.Shape, 'Rectangle', // the rectangular shape around the members
      { fill: 'rgba(128,128,128,0.2)', stroke: 'gray', strokeWidth: 3 }), $(go.Placeholder, { padding: 10 }) // represents where the members are
      ));
  // Create the Diagram's Model:
  const nodeDataArray = [
      { key: 1, text: 'Alpha', color: '#B2DFDB', state: 'one' },
      { key: 2, text: 'Beta', color: '#B2B2DB', state: 'two', password: '1234' },
      { key: 3, text: 'Gamma', color: '#1DE9B6', state: 2, group: 5, flag: false, choices: [1, 2, 3, 4, 5] },
      { key: 4, text: 'Delta', color: '#00BFA5', state: 'three', group: 5, flag: true },
      { key: 5, text: 'Epsilon', color: '#00BFA5', isGroup: true }
  ];
  const linkDataArray = [
      { from: 1, to: 2, color: '#5E35B1' },
      { from: 2, to: 2, color: '#5E35B1' },
      { from: 3, to: 4, color: '#6200EA' },
      { from: 3, to: 1, color: '#6200EA' }
  ];
  myDiagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
  // myDiagram.model = go.Model.fromJson(document.getElementById('mySavedModel').value);
  // some shared model data
  myDiagram.model.modelData = { test: true, hello: 'world', version: 42 };
  // select a Node, so that the first Inspector shows something
  myDiagram.select(myDiagram.nodes.first());
  // Declare which properties to show and how.
  // By default, all properties on the model data objects are shown unless the inspector option "includesOwnProperties" is set to false.
  // Show the primary selection's data, or blanks if no Part is selected:
  const inspector1 = new Inspector('myInspectorDiv1', myDiagram, {
      // allows for multiple nodes to be inspected at once
      multipleSelection: true,
      // max number of node properties will be shown when multiple selection is true
      showLimit: 4,
      // when multipleSelection is true, when showUnionProperties is true it takes the union of properties
      // otherwise it takes the intersection of properties
      showUnionProperties: true,
      // uncomment this line to only inspect the named properties below instead of all properties on each object:
      // includesOwnProperties: false,
      properties: {
          'text': {},
          // key would be automatically added for nodes, but we want to declare it read-only also:
          'key': { readOnly: true, show: Inspector.showIfPresent },
          // color would be automatically added for nodes, but we want to declare it a color also:
          'color': { show: Inspector.showIfPresent, type: 'color' },
          // Comments and LinkComments are not in any node or link data (yet), so we add them here:
          'Comments': { show: Inspector.showIfNode },
          'LinkComments': { show: Inspector.showIfLink },
          'isGroup': { readOnly: true, show: Inspector.showIfPresent },
          'flag': { show: Inspector.showIfNode, type: 'checkbox' },
          'state': {
              show: Inspector.showIfNode,
              type: 'select',
              choices: function (node, propName) {
                  if (Array.isArray(node.data.choices))
                      return node.data.choices;
                  return ['one', 'two', 'three', 'four', 'five'];
              }
          },
          'choices': { show: false },
          // an example of specifying the <input> type
          'password': { show: Inspector.showIfPresent, type: 'password' }
      }
  });
  // Always show the first Node:
  const inspector2 = new Inspector('myInspectorDiv2', myDiagram, {
      // By default the inspector works on the Diagram selection.
      // This property lets us inspect a specific object by calling Inspector.inspectObject(object)
      inspectSelection: false,
      properties: {
          'text': {},
          // This property we want to declare as a color, to show a color-picker:
          'color': { type: 'color' },
          // key would be automatically added for node data, but we want to declare it read-only also:
          'key': { readOnly: true, show: Inspector.showIfPresent(myDiagram.selection.first(), 'key') }
      }
  });
  // If not inspecting a selection, you can programatically decide what to inspect (a Part, or a JavaScript object)
  // Here, we inspect the first node, if available
  const firstnode = myDiagram.nodes.first();
  if (firstnode !== null)
      inspector2.inspectObject(firstnode.data);
  // Always show the model.modelData:
  const inspector3 = new Inspector('myInspectorDiv3', myDiagram, {
      inspectSelection: false
  });
  inspector3.inspectObject(myDiagram.model.modelData);

  window.myDiagram = myDiagram; // Attach to the window for console debugging
  window.inspector1 = inspector1;
  window.inspector2 = inspector2;
  window.inspector3 = inspector3;
</script>
    </div>
    <!-- * * * * * * * * * * * * * -->
    <!--  End of GoJS sample code  -->
  </div>
</body>
<!--  This script is part of the gojs.net website, and is not needed to run the sample -->
<script src="../assets/js/goSamples.js"></script>
</html>
